package filter

import (
	"errors"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/context"
	"github.com/dgrijalva/jwt-go"
	"gowork/beegoToken/model"
	"net/url"
	"strings"
)

// ParseToken 解析JWT
func ParseToken(tokenString string) (*model.MemberClaims, error) {
	// 解析token
	// token, err := jwt.Parse(tokenString, func(token *jwt.Token) (i interface{}, err error) {
	// 	return MemberSecret, nil
	// })

	// 解析token
	token, err := jwt.ParseWithClaims(tokenString, &model.MemberClaims{}, func(token *jwt.Token) (i interface{}, err error) {
		return model.MemberSecret, nil
	})
	if err != nil {
		return nil, err
	}

	// if token.Valid {
	// 	fmt.Println(token.Claims) // 校验token
	// 	return token.Claims.(*MemberClaims), nil   //报错
	// }

	if claims, ok := token.Claims.(*model.MemberClaims); ok && token.Valid { // 校验token
		return claims, nil
	}
	return nil, errors.New("invalid token")
}

func init()  {
	var filterToken = func(ctx *context.Context) {
		// 需要被过滤的地址 一定要写键值
		filter_map := map[string]string{
			"/login":"登录",
		}
		urlStr := ""
		tmpUrl ,err := url.Parse(ctx.Request.RequestURI)
		if err == nil {
			urlStr = tmpUrl.Path
		}
		if res := filter_map[urlStr] ;  res == "" {
			/** 不在 Map 内对请求进行处理 **/
			// 待验证数据
			waitingValidate := make([]string,1,1)
			// headerToken
			headerToken := ctx.Request.Header.Get("token")
			waitingValidate = append(waitingValidate,headerToken)

			// paramToken
			paramToken := ctx.Request.Form.Get("token")
			waitingValidate = append(waitingValidate,paramToken)

			//serviceInstance := service.BaseService{
			//	Ctx:ctx,
			//}
			//paramToken := (serviceInstance.GetData())["token"]
			//val , ok := paramToken.(string)
			//if ok {
			//	// 断言成功 如果真的是字符串 加入到等待判断列表
			//	waitingValidate = append(waitingValidate,val)
			//}

			// 循环验证多处token是否有效
			//var successTokenContent *map[string]interface{}
			var t string
			for _ ,val := range waitingValidate {
				if val != "" {
					t = val
					break
				}
			}

			if t == "" {
				ctx.Output.JSON(map[string]interface{}{"message": "请求头中auth为空", "requestCode": 2003}, false, false)
				return
			}

			// 按空格分割
			parts := strings.SplitN(t, " ", 2)
			if !(len(parts) == 2 && parts[0] == "Bearer") {
				ctx.Output.JSON(map[string]interface{}{"message": "请求头中auth格式有误", "requestCode": 2004}, false, false)
				return
			}

			// parts[1]是获取到的tokenString，我们使用之前定义好的解析JWT的函数来解析它
			_, err := ParseToken(parts[1])
			if err != nil {
				ctx.Output.JSON(map[string]interface{}{"message": "无效的Token", "requestCode": 2005}, false, false)
				return
			}

			//var authToken auth.Token
			//for _ ,val := range waitingValidate {
			//	if val != "" {
			//		authToken.Token = val
			//		item , ok := authToken.ValidateToken()
			//		if ok {
			//			successTokenContent = item
			//		}
			//	}
			//}

			// 如果循环全部结果都都没有通过验证的直接返回登录失效
			//if successTokenContent == nil {
			//	// 创建返回对象
			//	tmpErrInfo := map[string]interface{}{
			//		"desc-en":"TokenValidateError",
			//		"desc-zh":"Token验证失败",
			//	}
			//	ret := returnMessage.NewRetJson().
			//		SetCode(enum.HttpCodeError).
			//		SetMsg(enum.GetHttpCodeText(enum.HttpCodeFailure)).
			//		SetData(tmpErrInfo)
			//	ctxPtr := tool.CtxPtr{
			//		Ctx:ctx,
			//	}
			//	ctxPtr.QuickRetJson(ret)
			//	return
			//}
			//// 如果验证通过 这里再调用一下续签
			//authToken.Token = (*successTokenContent)["token"].(string)
			//authToken.RenewToken()
			//ctx.Input.SetData("tokenData",successTokenContent)
		}
	}
	beego.InsertFilter("/*",beego.BeforeRouter,filterToken)
}
